package pais.db;

import papos.rowset.StorageSystem;
import pasys.error.PaposException;

public class PAISDB {
  public static int PAGE_SIZE = 2048;
  private static PAISDB INST_ = null;
  boolean isOpen_ = false;
  String dbPath_ ;
  public static PAISDB getInstance(String dbPath) {
    if ( INST_ == null ) {
      INST_ = new PAISDB(dbPath);
    }
    return INST_;
  }
  private TableInterface tables_[];

  public PAISDB(String dbpath) {
    tables_ = new TableInterface[] {
        PAISSystemTable.createInstance(dbpath),
        KeywordTable.createInstance(dbpath),
        HtmlPageTable.createInstance(dbpath)
    };
    dbPath_ = dbpath;
  }

  public void open(boolean writable, int bufferPageCount) throws PaposException{
    if ( ! isOpen_ ) {
      StorageSystem.openMeta( dbPath_, bufferPageCount, PAGE_SIZE );
      try {
        for (int i=0; i<tables_.length; i++) {
          tables_[i].open(writable);
        }
      } catch ( Exception e ) {
        e.printStackTrace();
        PAISDB.exit("Database Open Error : "+e.toString());
      }
      isOpen_ = true;
    }
  }

  public void close() throws PaposException {
    if ( isOpen_ ) {
      try {
        for (int i=tables_.length-1; i>=0; i--) {
          tables_[i].close();
        }
      } catch ( Exception e ) {
        e.printStackTrace();
        System.out.println("Database Close Error : "+e.toString());
        System.exit(-1);
      } finally {
        StorageSystem.closeMeta();
      }
      isOpen_ = false;
    }
  }

  public void sync() {
    assert(isOpen_);

    try {
      for (int i=tables_.length-1; i>=0; i--) {
        tables_[i].sync();
      }
    } catch ( Exception e ) {
      e.printStackTrace();
      PAISDB.exit("Database Sync Error : "+e.toString());
    }
  }
  public static void exit(String message) {
    try {
      getInstance(null).close();
    } catch (PaposException e) {
      e.printStackTrace();
    }
    System.err.println(message);
    System.exit(-1);
  }
  public static void exitPrintingStack(String message) {
    try {
      getInstance(null).close();
    } catch (PaposException e) {
      e.printStackTrace();
    }
  
    System.err.println(message);
    try {
      throw new Exception();
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.exit(-1);
  }
}
